/*******************************************************************/
/*
archivo: manejadorBits.cpp
*/
/*******************************************************************/

#include "StateControl.h"
#include <iostream>
//using namespace std;

StateControl::StateControl() {
	this->contadorUF = 0;
	this->contadorOV = 0;

}

StateControl::~StateControl() {
}

void StateControl::asignar() {
	int j=0;
	int i;
	for(i=31; i>=0; i--) {
		this->nPiso[i].b1= piso>>j;
		this->nTecho[i].b1= techo>>j;
		j++;
	}

	cout<<"Vtecho: ";
	for(i=0;i<32;i++)
		cout<<nTecho[i].b1;
	cout<<endl;
	cout<<"Vpiso:  ";

	for(i=0;i<32;i++)
			cout<<nPiso[i].b1;
		cout<<endl;



}

void StateControl::setPiso(int piso) {
    this->piso=piso;
}

void StateControl::setTecho(int techo) {
    this->techo=techo;
}

int StateControl::getPiso()  {
    return this->piso;
}

int StateControl::getTecho() {
    return this->techo;
}

/*empaquetado* StateControl::getVPiso() {
	return &this->nPiso;
}*/

/*empaqutetado* StateControl::getVTecho() {
	return &this->nTecho;
}*/

unsigned int StateControl::getContadorUF() {
	return contadorUF;
}

unsigned int StateControl::getContadorOV() {
	return contadorOV;
}

string StateControl::getEmision () {
	return emision;
}

void StateControl::agregarPading() {
	char caracter;
	byte = (byte<<1) +1; // se agrega un 1 en el byte
	contadorCaracter++;
	if(contadorCaracter<8) {
		while (8-contadorCaracter>0) {
			byte= byte<<1;	//se completa con ceros el byte
			contadorCaracter++;
		}
	}

	if(contadorCaracter==8) {

		caracter = static_cast<char>(byte);
		cout<<"ultimo caracter "<<caracter<<"ultimo byte: "<<byte<<endl;
		cout<<"emision"<<emision[2]<<endl;
		emision = emision + caracter;
		cout<<"emision"<<emision[0]<<emision[2]<<endl;
	}
}

/*unsigned int StateControl::vectorToInt(const empaquetado* vector[32]) {
	unsigned int entero=0;
	unsigned int i;

	for (i=0;i<32;i++) {
		entero += *vector[i]->b1;
		entero = entero<<1;
	}

	return entero;
}*/

void StateControl::mostrarVector(empaquetado vectorBits[32], string nombre) {
	int i;
	cout<<nombre;

	for(i=0;i<32;i++)
		cout<<vectorBits[i].b1;

	cout<<endl;

}

void StateControl::normalizar() {

	mostrarBinario(this->piso,"pison");
	mostrarBinario(this->techo,"techon");

	//cout<<"entro1"<<endl;
	this->controlOverflow();
	//cout<<"entro2"<<endl;
	this->controlUnderflow();
	cout<<"contadorUF: "<<contadorUF<<endl;

	cout<<"tamanio byte: "<<sizeof (empaquetado)<<endl;



}

void StateControl::mostrarBinario(unsigned int binario, string nombre) {
	int j=0;
	int i;
	empaquetado vectorBits[32];
	for (i=31;i>=0;i--) {
		vectorBits[i].b1=binario>>j;
		j++;
	}
	cout<<nombre<<" ";
	for(i=0;i<32;i++)
		cout<<vectorBits[i].b1;
	cout<<endl;
}

void StateControl::controlUnderflow () {


	int i;

	if ((this->nPiso[0].b1==0) && (this->nTecho[0].b1==1)) {
		cout<<"entro"<<endl;
    	if ((this->nPiso[1].b1==1) && (this->nTecho[1].b1==0)) {
    		cout<<"entro2"<<endl;
    		this->contadorUF++;
    		i=2;
    		while ((this->nPiso[i].b1==1) && (this->nTecho[i].b1==0) && (i<30)) {
    			this->contadorUF++;
    			i++;
    		}
    	}
    }

   /* OpePiso = ~0;
  //  this->mostrarBinario(OpePiso,"OpePiso");
    OpeTecho = (OpePiso >>1) + 1;
    //this->mostrarBinario(OpeTecho,"OpeTecho");
    OpePiso= OpeTecho>>1;
    //this->mostrarBinario(OpePiso,"OpePiso");
    operando= OpePiso | OpeTecho;
    //this->mostrarBinario(operando,"operando");


    auxPiso = OpePiso & this->piso;
    auxTecho= OpeTecho & this->techo;*/
    //cout<<"opePiso: "<<OpePiso<<" opeTecho"<<OpeTecho<<endl;
    //cout<<"auxPiso: "<<auxPiso<<" auxTecho"<<auxTecho<<endl;
    /*this->mostrarBinario(OpePiso,"OpePiso");
    this->mostrarBinario(auxPiso,"auxPiso");
    this->mostrarBinario(OpeTecho,"OpeTecho");
    this->mostrarBinario(auxTecho,"auxTecho");*/

   /* if((OpePiso-auxPiso==0) && (OpeTecho-auxTecho==0)) {
    	UF = true;
    	cout<<"Es UF"<<endl;
    }
    else
    	cout<<"no es UF"<<endl;
    if(UF) {
    	contadorUF = 0;
    	unsigned int comparador = ~0;
    	comparador = comparador >> 1;
    	//mostrarBinario(comparador,"comparador");
    	auxPiso=this->piso<<2;
    	auxTecho = this->techo<<2;
    	//mostrarBinario(auxPiso,"auxpiso");
    	//mostrarBinario(auxTecho,"auxtecho");
    	int i =0;
    	while((auxPiso>comparador)&&(auxTecho<comparador)&&(i<30)) {
    		contadorUF += 1;
    		auxPiso= auxPiso << 1;
    		auxTecho = auxTecho << 1;
			i++;
    	}
    }*/

}

void StateControl::controlOverflow() {
	bool iguales= true;
	int contador = 0;
	unsigned int i =0;
	unsigned int j;
	empaquetado bit;
	bit.b1= this->nTecho[0].b1;
	while ((iguales) && (i<32)) {
		if(this->nPiso[i].b1 == this->nTecho[i].b1) {

			if (this->contadorUF>0) {
				this->almacenarSalida(bit);

				for (j=0;j<contadorUF;j++) {
					bit.b1= ~bit.b1;
					this->almacenarSalida(bit);

				}


				this->contadorUF = 0;

			}
			else
				this->almacenarSalida(nTecho[i]);

			contador++;
			i++;
		}
		else
			iguales = false;
	}

	cout<<"OV"<<contador<<endl;
	this->contadorOV = contador;

	/*vector[0].b1=this->nTecho[0].b1;
	cout<<vector[0].b1<<endl;
	cout<<nTecho[1].b1<<endl;

	if ((contador>0)&&(this->contadorUF>0)) {
		cout<<"UF"<<contadorUF<<endl;
		for(i=1; i<this->contadorUF;i++)
			vector[i].b1=~vector[0].b1;
		this->contadorUF = 0;
	}

	for (j=1;j<contador; j++)
		vector[i].b1=this->nTecho[j].b1;



	this->mostrarVector(vector,"emision");*/

}

void StateControl::almacenarSalida(empaquetado bit) {
	char caracter;


	if(contadorCaracter<8) {
		byte = byte<<1;
		byte = byte + bit.b1;
		cout<<bit.b1;
		contadorCaracter++;
	}

	else {
		cout<<endl;
		caracter = static_cast<char>(byte);

		cout<<"caracter: "<<caracter<<" byte: "<<byte<<endl;
		emision = emision + caracter;
		contadorCaracter=0;
	}
}
